<script setup>
import { ref, computed, nextTick, onMounted, reactive } from "vue";
import { useProcessStoreHook } from "../../store/modules/process";
import { useDetectionStoreHook } from "../../store/modules/detection";
import { useInfoStoreHook } from "../../store/modules/info";
import { useTableDragger } from "../../utils/dragger";
import { getShiftTime, time2string } from "../../utils/datetime";
import { ElMessage, ElMessageBox } from "element-plus";

const timesTableInnerRef = ref(null);

const processStore = useProcessStoreHook();
const detection = useDetectionStoreHook();
const userInfo = useInfoStoreHook();

const timeColumns = ref([]);

const timeColumnsTimer = () => {
  const timeRange = getShiftTime();
  // 获取当前的时间列
  const result = [];
  while (timeRange[0] < timeRange[1]) {
    timeRange[0].setHours(timeRange[0].getHours() + 1);
    result.push(
      `${timeRange[0].getHours().toString().padStart(2, "0")}:${timeRange[0].getMinutes()}`
    );
  }
  timeColumns.value = result;
  setTimeout(() => {
    timeColumnsTimer();
  }, 10 * 1000);
};

onMounted(() => {
  timeColumnsTimer();
});

const highlightIndex = ref(0);

let lastMinute = -1;

async function highlightItemTimer() {
  const nowMinute = new Date().getMinutes();
  if (lastMinute !== nowMinute) {
    lastMinute = nowMinute;
    const timeRange = getShiftTime();
    highlightIndex.value = Math.floor((new Date() - timeRange[0]) / 1000 / 3600);
    let scrollLeft = 0;
    if (highlightIndex.value > 5) {
      scrollLeft = 13 * 80;
    }
    await detection.updateDataset();
    await nextTick(() => timesTableInnerRef.value.scrollBarRef.setScrollLeft(scrollLeft));
  }
  setTimeout(async () => {
    await highlightItemTimer();
  }, 1000);
}
onMounted(highlightItemTimer);

const highlightNowItem = ({ row, columnIndex }) => {
  const col = columnIndex - 1;
  const style = {};
  const html = document.querySelector("html");
  const isDark = html.classList.value.indexOf("dark") !== -1;
  // 因为表头多了一列“操作员”，因此忽略掉第一行，并且所有的columnIndex需要减1
  if (columnIndex !== 0 && col < highlightIndex.value) {
    style["color"] = row[col] === 0 ? "#ff4949" : "#13ce66";
  } else if (col === highlightIndex.value) {
    style["background-color"] = isDark ? "#18222c" : "#f3f3f7";
    style["color"] = row[col] === 0 ? "#e6a23c" : "#13ce66";
  } else {
    return;
  }
  return style;
};

const tableData = computed(() => {
  const result = [];
  detection.dataset.forEach((ds) => {
    if (ds.process != processStore.processSrc) return;
    const item = { ...ds };
    const data = [...item.data];
    delete item.data;
    data.forEach((d) => (item[d.type] = d.value));
    if (item.work_type === userInfo.work_type) result.push(item);
  });
  return result;
});

const timesData = computed(() => {
  const timeRange = getShiftTime();
  const statistic = new Array(3);
  statistic[0] = new Array(12).fill(0);
  statistic[1] = new Array(12).fill(0);
  statistic[2] = new Array(12).fill(0);
  tableData.value.forEach((d) => {
    const index = Math.floor((d.create_at - timeRange[0]) / 1000 / 3600);
    statistic[d.identity][index] += 1;
  });
  const worker = { operator: "操作员" };
  const monitor = { operator: "班组长" };
  const inspector = { operator: "巡检员" };
  for (let i = 0; i < 12; i++) {
    worker[i] = statistic[0][i];
    monitor[i] = statistic[1][i];
    inspector[i] = statistic[2][i];
  }
  return [worker, monitor, inspector];
});

const timesTableDragger = useTableDragger(timesTableInnerRef);

const anomalyList = ref([]);

async function toGetAnomalyList() {
  const timeRange = getShiftTime();
  const res = await window.api.getAnomaly(
    processStore.workCenterId,
    processStore.processSrc,
    timeRange[0],
    timeRange[1]
  );
  anomalyList.value = res;
  anomalyList.value = anomalyList.value.map((item) => {
    item.create_at = time2string(item.create_at);
    return { ...item };
  });
}
onMounted(toGetAnomalyList);

const reportData = reactive({
  time: [],
  content: "待机"
});

const reportVisible = ref(false);

function onCellClick(index) {
  const timeRange = getShiftTime();
  timeRange[0].setHours(timeRange[0].getHours() + index);
  timeRange[1] = new Date(timeRange[0]);
  timeRange[1].setHours(timeRange[1].getHours() + 1);
  if (timeRange[1] >= new Date()) return;
  reportData.time = [timeRange[0], timeRange[1]];
  const time = time2string(reportData.time[0]) + " ~ " + time2string(reportData.time[1]);
  for (let i = 0; i < anomalyList.value.length; i++) {
    const item = anomalyList.value[i];
    if (item.time === time) {
      ElMessage.warning("请勿重复提报异常！");
      return;
    }
  }
  reportVisible.value = true;
}

async function toReportAnomaly() {
  ElMessageBox.confirm("确认进行异常报备吗？", "提示", {
    type: "warning"
  })
    .then(() => {
      const time = time2string(reportData.time[0]) + " ~ " + time2string(reportData.time[1]);
      if (!processStore.workCenterId) {
        ElMessage.error("请先选择产线再进行操作");
        return;
      }
      if (!processStore.processSrc) {
        ElMessage.error("请先选择工序再进行操作");
        return;
      }
      if (!userInfo.username) {
        ElMessage.error("请先登录再进行操作");
        return;
      }
      window.api
        .insertAnomaly({
          workCenterId: processStore.workCenterId,
          workCenterName: processStore.workCenterDesc,
          content: reportData.content,
          processId: processStore.processSrc,
          processName: processStore.processName,
          time: time,
          reporter: userInfo.username,
          create_at: +new Date()
        })
        .then((res) => {
          if (res) {
            ElMessage.success("已完成提报");
            reportVisible.value = false;
            toGetAnomalyList();
          } else {
            console.log(res);
            ElMessage.error("提报失败，请重试或联系管理员解决");
          }
        })
        .catch((err) => {
          console.log(err);
          ElMessage.error("未知错误，请联系管理员解决");
        });
    })
    .catch(() => {});
}
</script>

<template>
  <div class="box">
    <div class="times-table">
      <el-table
        ref="timesTableInnerRef"
        style="user-select: none"
        stripe
        border
        :data="timesData"
        :cell-style="highlightNowItem"
        @mousedown="timesTableDragger.mouseDownHandler"
        @mouseup="timesTableDragger.mouseUpHandler"
        @mousemove="timesTableDragger.mouseMoveHandler"
        @mouseleave="timesTableDragger.mouseUpHandler"
      >
        <el-table-column fixed="left" prop="operator" label="操作人" :resizable="false" />
        <el-table-column
          v-for="(item, index) in timeColumns"
          :key="index"
          :prop="index.toString()"
          :label="item"
          :resizable="false"
        >
          <template #default="{ row }">
            <div class="table-cell" @click="onCellClick(index)">{{ row[index.toString()] }}</div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="tips">提示：时间列名表示一个时间段的结束时间，如8:30-9:30的时间落在9:30的列上</div>
    <el-divider />
    <div class="anomaly-title">异常提报记录</div>
    <el-table :data="anomalyList" height="320px">
      <el-table-column label="异常时段" prop="time" />
      <el-table-column label="异常原因" prop="content" />
      <el-table-column label="记录时间" prop="create_at" />
    </el-table>
  </div>
  <el-dialog v-model="reportVisible">
    <el-form>
      <el-form-item label="异常时段">
        <el-date-picker
          class="datetime-picker"
          size="large"
          readonly
          type="datetimerange"
          v-model="reportData.time"
        />
      </el-form-item>
      <el-form-item label="异常时段">
        <el-radio-group class="radio-group" size="large" v-model="reportData.content">
          <el-radio-button label="待机" />
          <el-radio-button label="故障" />
          <el-radio-button label="型号更换" />
        </el-radio-group>
      </el-form-item>
      <el-button
        plain
        type="primary"
        style="width: 100%; height: 56px !important"
        @click="toReportAnomaly"
        >提报异常</el-button
      >
    </el-form>
  </el-dialog>
</template>

<style lang="scss" scoped>
.box {
  height: calc(100% - 24px);
  margin: 0 12px 24px 12px;
}
.times-table {
  height: 160px;
}
.tips {
  color: #888;
  margin-top: 14px;
  font-size: 14px;
}
.anomaly-title {
  margin: 12px 0 12px 8px;
}
:deep(.header-box) {
  display: flex;
  height: 24px;
  line-height: 24px;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  .el-icon {
    margin-right: 4px;
  }
}
.selection {
  height: 90% !important;
  width: 100% !important;
  font-size: 22px !important;
  margin: 12px !important;
}
:deep(.el-table th > .cell) {
  white-space: pre-wrap;
}
.table-cell {
  height: 100%;
  width: 100%;
}
:deep(.datetime-picker) {
  .el-range-input {
    font-size: 16px;
  }
}
:deep(.radio-group) {
  .el-radio-button__inner {
    font-size: 16px;
  }
}
</style>
